package cn.smxy.user.controller;

import cn.smxy.constant.RegexConstant;
import cn.smxy.excel.UserExcel;
import cn.smxy.param.*;
import cn.smxy.pojo.User;
import cn.smxy.user.config.AliyunOSSUtil;
import cn.smxy.user.listener.ExcelUserListener;
import cn.smxy.user.service.UserService;
import cn.smxy.util.R;
import com.alibaba.excel.EasyExcel;
import com.auth0.jwt.JWT;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;
    @Autowired
    private AliyunOSSUtil aliyunOSSUtil;


    /**
     * 校验用户账号接口
     *
     * @param userCheckParam
     * @param result
     * @return
     */
    @PostMapping("/check")
    public R check(@RequestBody UserCheckParam userCheckParam, BindingResult result) {
        if (result.hasErrors()) {
            return R.fail("账号为空，不可使用");
        }
        return userService.check(userCheckParam);
    }

    /**
     * 用户注册接口
     *
     * @param user
     * @param result
     * @return
     */
    @PostMapping("/register")
    public R register(@RequestBody @Validated User user, BindingResult result) {
        if (result.hasErrors()) {
            return R.fail("参数异常，注册失败");
        }
        return userService.register(user);
    }

    /**
     * 用户账号登录接口
     *
     * @param loginAccountParam
     * @param result
     * @return
     */
    @PostMapping("/login/account")
    public R loginAccount(@RequestBody @Validated LoginAccountParam loginAccountParam, BindingResult result) {
        if (result.hasErrors()) {
            return R.fail("参数异常，登录失败");
        }
        return userService.loginAccount(loginAccountParam);
    }

    /**
     * 用户邮箱登录接口
     *
     * @param loginEmailParam
     * @param result
     * @return
     */
    @PostMapping("/login/email")
    public R loginEmail(@RequestBody @Validated LoginEmailParam loginEmailParam, BindingResult result) {
        if (result.hasErrors()) {
            return R.fail("参数异常，登录失败");
        }
        return userService.loginEmail(loginEmailParam);
    }

    /**
     * 用户绑定邮箱接口
     * @param loginEmailParam
     * @param result
     * @return
     */
    @PutMapping("/bind/email")
    public R bindEmail(@RequestBody @Validated LoginEmailParam loginEmailParam, BindingResult result) {
        if (result.hasErrors()) {
            return R.fail("参数异常，登录失败");
        }
        return userService.bindEmail(loginEmailParam);
    }

    /**
     * 用户手机号登录接口
     *
     * @return
     */
    @PostMapping("/login/phone")
    public R loginPhone() {
        return null;
    }

    /**
     * 图片上传接口(上传用户头像)
     *
     * @param img
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Object upload(@RequestPart("img") MultipartFile img) throws Exception {
        String filename = img.getOriginalFilename();
        String contentType = img.getContentType();
        long millis = System.currentTimeMillis();
        filename = millis + filename; // 防止重名
        String url = aliyunOSSUtil.uploadImage(filename, img.getBytes(), contentType, 1440);
        String[] urls = url.split("\\?");
        System.out.println("url = " + urls[0]);
        return R.ok("上传成功", urls[0]);
    }

    /**
     * 用户修改个人信息接口
     *
     * @param user
     * @return
     */
    @PutMapping("/update")
    public R update(@RequestBody User user) {
        return userService.update(user);
    }

    /**
     * 返回用户基本信息接口
     *
     * @param userId 用户id
     * @return
     */
    @GetMapping("/basic/{userId}")
    public User basic(@PathVariable Long userId) {
        return userService.basic(userId);
    }

    /**
     * 获取用户信息接口 利用token
     *
     * @param request
     * @return
     */
    @GetMapping("/info")
    public R info(HttpServletRequest request) {
        String authorization = request.getHeader("Authorization");
        List<String> audience = JWT.decode(authorization).getAudience();
        return userService.info(Long.parseLong(audience.get(0)));
    }

    /**
     * 获取用户名称接口
     *
     * @param userId
     * @return
     */
    @GetMapping("/info/{userId}")
    public User getUserName(@PathVariable Long userId) {
        return userService.getUserName(userId);
    }

    /**
     * 用户退出登录接口
     *
     * @param request
     */
    @PostMapping("/logout")
    public R logout(HttpServletRequest request) {
        String authorization = request.getHeader("Authorization");
        List<String> audience = JWT.decode(authorization).getAudience();
        String token = audience.get(0);
        return userService.logout(token);
    }

    /**
     * 发送邮箱接口
     *
     * @param emailParam
     * @return
     */
    @PostMapping("/email")
    public R toEmail(@RequestBody @Validated EmailParam emailParam, BindingResult result) {
        if (result.hasErrors()) {
            return R.fail("参数错误");
        }
        if (emailParam.getTag() == 0 && userService.checkEmail(emailParam.getUserEmail()) > 0L) {
            return R.fail("该邮箱已被注册过");
        }
        Pattern pattern = Pattern.compile(RegexConstant.EMAIL);
        Matcher matcher = pattern.matcher(emailParam.getUserEmail());
        if (!matcher.matches()) {
            return R.fail("邮箱格式错误");
        } else {
            return userService.toEmail(emailParam);
        }
    }


    // TODO: 管理员模块

    /**
     * excel批量导入接口
     *
     * @param file excel文件
     * @return
     */
    @PostMapping(value = "/save/excel", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public R saveExcel(@RequestPart("file") MultipartFile file) throws IOException {
        EasyExcel.read(file.getInputStream(), User.class, new ExcelUserListener(userService)).sheet().doRead();
        return R.ok("success");
    }

    /**
     * 分页展示用户接口
     *
     * @param pageParam
     * @return
     */
    @PostMapping("/page")
    public R page(@RequestBody PageParam pageParam) {
        IPage<User> page = new Page(pageParam.getCurrentPage(), pageParam.getPageSize());
        page = userService.page(page, null);
        long total = page.getTotal();
        List<User> records = page.getRecords();
        return R.ok("查询成功", records, total);
    }


    /**
     * 删除用户接口
     *
     * @param userId
     * @return
     */
    @DeleteMapping("/delete/{userId}")
    public R delete(@PathVariable Long userId) {
        return userService.delete(userId);
    }

    /**
     * 模糊分页查询用户名接口
     *
     * @param userSearchParam
     * @return
     */
    @PostMapping("/search")
    public R search(@RequestBody UserSearchParam userSearchParam) {
        return userService.search(userSearchParam);
    }

    /**
     * excel导出接口
     *
     * @return
     * @throws MalformedURLException
     */
    @PostMapping("/all")
    public List<UserExcel> getAll() throws MalformedURLException {
        return userService.getAll();
    }

}
